﻿using System;
using BP.DA;
using BP.En;
using System.Data;

namespace BP.Demo
{
    /// <summary>
    /// 推断记录 属性
    /// </summary>
    public class RptDtlAttr : EntityNoNameAttr
    {
        /// <summary>
        /// 推断记录内容
        /// </summary>
        public const string Docs = "Docs";
    }
    /// <summary>
    /// 推断记录
    /// </summary>
    public class RptDtl : EntityMyPK
    {
        #region 构造方法
        /// <summary>
        /// 权限控制
        /// </summary>
        public override UAC HisUAC
        {
            get
            {
                UAC uac = new UAC();
                uac.IsUpdate = true;
                uac.IsInsert = true;
                return uac;
            }
        }
        /// <summary>
        /// 推断记录
        /// </summary>
        public RptDtl()
        {
        }
        public RptDtl(string no)
        {
            SetValByKey(EntityNoNameAttr.No, no);
            Retrieve();
        }
        /// <summary>
        /// 重写基类方法
        /// </summary>
        public override Map EnMap
        {
            get
            {
                if (_enMap != null)
                    return _enMap;

                Map map = new Map("Demo_RptDtl", "推断记录");

                map.AddGroupAttr("编码数据");
                map.AddMyPK();
                map.AddTBString("RptMyPK", null, "报告编号", true, true, 0, 100, 10, true);
                map.AddTBString("StockNo", null, "推断编号", true, true, 0, 100, 10, true);
                map.AddTBString("TradeNo", null, "交易编号", true, true, 0, 100, 10, true);
                map.AddTBDate("TradeName", null, "交易日期", true, true); //交易日期.
                map.AddTBString("StockNo", null, "Stock编号", false, false, 0, 300, 100);

                map.AddGroupAttr("采集数据");
                map.AddTBMoney("CloseNum", 0, "收盘价", true, true);
                map.AddTBMoney("MaxNum", 0, "最高", true, true);
                map.AddTBMoney("MinNum", 0, "最低", true, true);
                map.AddTBMoney("SwingNum", 0, "振幅金额", true, true);

                map.AddGroupAttr("预测数据");
                map.AddTBMoney("StockCloseNum", 0, "收盘价", true, true);
                map.AddTBMoney("StockMax", 0, "最高", true, true);
                map.AddTBMoney("StockMin", 0, "最低", true, true);
                map.AddTBMoney("StockSwing", 0, "振幅金额(路宽)", true, true);
                map.AddTBMoney("StockCenter", 0, "中线位置AVG", true, true);
                map.AddTBMoney("StockSafeTop", 0, "高抛(安全线)", true, true);
                map.AddTBMoney("StockSafeDown", 0, "低吸(安全线)", true, true);

                map.AddGroupAttr("实际数据");
                map.AddTBMoney("ResultCloseNum", 0, "实际收盘价", true, true);
                map.AddTBMoney("ResultMax", 0, "实际最高金额", true, true);
                map.AddTBMoney("ResultMin", 0, "实际最低金额", true, true);

                map.AddGroupAttr("预测执行结果");
                map.AddTBInt("IsTop", 0, "是否命中高位?", true, true);
                map.AddTBInt("IsDown", 0, "是否命中低位?", true, true);
                map.AddTBInt("ResultSta", 0, "计算状态", true, true); //@0=完美,1=高位命中,@低位命中,@失败
                map.AddTBString("JNote", null, "预测说明", true, true, 0, 600, 10, true);

                map.AddGroupAttr("操作数据");
                map.AddTBMoney("Outgo", 0, "支出", true, true);
                map.AddTBMoney("Income", 0, "收入", true, true);
                map.AddTBMoney("Win", 0, "累计盈利", true, true);
                map.AddTBString("ExecNote", null, "交易执行", true, true, 0, 600, 10, true);

                map.AddTBInt("IsOK", 0, "是否计算通过?", true, true);

                _enMap = map;
                return _enMap;
            }
        }
        #endregion


        public Trade GetNextDay()
        {
            string sql = "SELECT No FROM Demo_Trade WHERE No >'" + TradeNo + "' LIMIT 1";
            DataTable dt = DBAccess.RunSQLReturnTable(sql);
            if (dt.Rows.Count == 0)
                return null;
            string no = dt.Rows[0][0] as string;

            Trade td = new Trade();
            td.No = no;
            td.Retrieve();
            return td;
        }
        /// <summary>
        /// 求平均数模式
        /// </summary>
        /// <param name="rpt"></param>
        public void DoStockMode_Avg(Rpt rpt)
        {
            //获得最近5天的最高值，求平均数，作为最高金额.
            string sql = "SELECT AVG(MaxNum) as Num FROM (SELECT MaxNum FROM Demo_Trade WHERE No <= '" + TradeNo + "' ORDER BY No DESC LIMIT " + rpt.NearDays + ") AS subquery ";
            StockMax = DBAccess.RunSQLReturnValDecimal(sql, 0, 2);

            ///最低值.
            sql = "SELECT AVG(MinNum) as Num FROM (SELECT MinNum FROM Demo_Trade WHERE No <= '" + TradeNo + "' ORDER BY No DESC LIMIT " + rpt.NearDays + ") AS subquery ";
            StockMin = DBAccess.RunSQLReturnValDecimal(sql, 0, 2);

            //路宽
            sql = "SELECT AVG(SwingNum) as Num FROM (SELECT SwingNum FROM Demo_Trade WHERE No <= '" + TradeNo + "' ORDER BY No DESC LIMIT " + rpt.NearDays + ") AS subquery ";
            SwingNum = DBAccess.RunSQLReturnValDecimal(sql, 0, 2);

            //收盘价
            sql = "SELECT AVG(CloseNum) as Num FROM (SELECT CloseNum FROM Demo_Trade WHERE No <= '" + TradeNo + "' ORDER BY No DESC LIMIT " + rpt.NearDays + ") AS subquery ";
            StockCloseNum = DBAccess.RunSQLReturnValDecimal(sql, 0, 2);

            // 1.中线位置.
            StockCenter = (StockMax + StockMin) / 2;
            //2. 车宽.
            decimal careWidthHalf = rpt.CarWidth / 2 / 100; //转化为分.

            StockSafeTop = StockCenter + careWidthHalf; //抛线.
            StockSafeDown = StockCenter - careWidthHalf; //吸线.
        }
        /// <summary>
        /// 按照平均数来预测
        /// </summary>
        /// <returns></returns>
        public string DoStockModel1(Rpt rpt)
        {

            //1. 填写预测数据.
            #region 1. 做预测. //求平均数模式.
            DoStockMode_Avg(rpt);
            #endregion 做预测.


            #region 2. 获得上一天的数据存储到数据库.
            Trade tdNextDay = GetNextDay();
            if (tdNextDay == null)
                return "err@没有找到，下一天的数据.";

            ResultMax = tdNextDay.MaxNum;
            ResultMin = tdNextDay.MinNum;
            ResultCloseNum = tdNextDay.CloseNum;
            #endregion 获得上一天的数据存储到数据库.

            #region 3. 计算预测于之际的差.
            //最高值.
            if (StockSafeTop < ResultMax) IsTop = true; //卖出了.
            else
                IsTop = false; //没有卖出..

            //最低值.
            if (StockSafeDown > ResultMin) IsDown = true; //可以买入成交.
            else
                IsDown = false; //没有买到..


            if (IsTop && IsDown)
                ResultSta = 0; //完美.
            if (IsTop == false && IsDown == false)
                ResultSta = 3; //全翻车.

            if (IsTop == true && IsDown == false)
                ResultSta = 2; //没有买入.

            if (IsTop == false && IsDown == true)
                ResultSta = 1; //没有卖出.
            #endregion 获得上一天的数据存储到数据库.

            string note = "解析:";
            note += "\t\n 1.预测Max:" + StockMax + ",实际Max:" + ResultMax + "";
            note += "\t\n 2.预测Min:" + StockMin + ",实际Min:" + ResultMin + "";

            if (IsTop == true)
                note += "\t\n 3.安全Top:" + StockSafeTop + ",可卖出.";
            else
                note += "\t\n 3.安全Top:" + StockSafeTop + ",未卖出.实际最高价:" + ResultMax;

            if (IsDown == true)
                note += "\t\n 4.安全Down:" + StockSafeDown + ",已经买入.";
            else
                note += "\t\n 4.安全Down:" + StockSafeDown + ",未买入,实际最低价:" + ResultMin;


            string strs = "";
            if (ResultSta == 0) strs = "完美";
            if (ResultSta == 1) strs = "没有卖出";
            if (ResultSta == 2) strs = "没有买入";
            if (ResultSta == 3) strs = "全翻车";

            note += "\t\n 5.结果:" + ResultSta + "," + strs;

            JNote = note;
            IsOK = true;
            RptMyPK = rpt.MyPK;  //报告编号
            Update();
            return note;
        }


        #region 基本属性
        public string StockNo
        {
            get
            {
                return GetValStringByKey("StockNo");
            }
            set
            {
                SetValByKey("StockNo", value);
            }
        }
        /// <summary>
        /// 结果状态
        /// </summary>
        public int ResultSta
        {
            get
            {
                return GetValIntByKey("ResultSta");
            }
            set
            {
                SetValByKey("ResultSta", value);
            }
        }
        /// <summary>
        /// 支出
        /// </summary>

        public decimal Outgo
        {
            get
            {
                return GetValDecimalByKey("Outgo");
            }
            set
            {
                SetValByKey("Outgo", value);
            }
        }
        /// <summary>
        /// 收入
        /// </summary>
        public decimal Income
        {
            get
            {
                return GetValDecimalByKey("Income");
            }
            set
            {
                SetValByKey("Income", value);
            }
        }
        /// <summary>
        /// 计算成功？
        /// </summary>
        public bool IsOK
        {
            get
            {
                return GetValBooleanByKey("IsOK");
            }
            set
            {
                SetValByKey("IsOK", value);
            }
        }
        public decimal Win
        {
            get
            {
                return GetValDecimalByKey("Win");
            }
            set
            {
                SetValByKey("Win", value);
            }
        }
        /// <summary>
        /// 预测说明
        /// </summary>
        public string JNote
        {
            get
            {
                return GetValStringByKey("JNote");
            }
            set
            {
                SetValByKey("JNote", value);
            }
        }
        /// <summary>
        /// 执行命令.
        /// </summary>
        public string ExecNote
        {
            get
            {
                return GetValStringByKey("ExecNote");
            }
            set
            {
                SetValByKey("ExecNote", value);
            }
        }
        /// <summary>
        /// 报表编号
        /// </summary>
        public string RptMyPK
        {
            get
            {
                return GetValStringByKey("RptMyPK");
            }
            set
            {
                SetValByKey("RptMyPK", value);
            }
        }
        /// <summary>
        /// 交易编号
        /// </summary>
        public string TradeNo
        {
            get
            {
                return GetValStringByKey("TradeNo");
            }
            set
            {
                SetValByKey("TradeNo", value);
            }
        }
        /// <summary>
        /// 交易日期
        /// </summary>
        public string TradeName
        {
            get
            {
                return GetValStringByKey("TradeName");
            }
            set
            {
                SetValByKey("TradeName", value);
            }
        }
        /// <summary>
        /// 最高值
        /// </summary>
        public decimal MaxNum
        {
            get
            {
                return GetValDecimalByKey("MaxNum");
            }
            set
            {
                SetValByKey("MaxNum", value);
            }
        }
        /// <summary>
        /// 最低值
        /// </summary>
        public decimal MinNum
        {
            get
            {
                return GetValDecimalByKey("MinNum");
            }
            set
            {
                SetValByKey("MinNum", value);
            }
        }
        public decimal CloseNum
        {
            get
            {
                return GetValDecimalByKey("CloseNum");
            }
            set
            {
                SetValByKey("CloseNum", value);
            }
        }
        public decimal SwingNum
        {
            get
            {
                return GetValDecimalByKey("SwingNum");
            }
            set
            {
                SetValByKey("SwingNum", value);
            }
        }
        public decimal SwingRate
        {
            get
            {
                return GetValDecimalByKey("SwingRate");
            }
            set
            {
                SetValByKey("SwingRate", value);
            }
        }
        public decimal StockCloseNum
        {
            get
            {
                return GetValDecimalByKey("StockCloseNum");
            }
            set
            {
                SetValByKey("StockCloseNum", value);
            }
        }
        public decimal StockMax
        {
            get
            {
                return GetValDecimalByKey("StockMax");
            }
            set
            {
                SetValByKey("StockMax", value);
            }
        }
        public decimal StockMin
        {
            get
            {
                return GetValDecimalByKey("StockMin");
            }
            set
            {
                SetValByKey("StockMin", value);
            }
        }

        public decimal StockSwing
        {
            get
            {
                return GetValDecimalByKey("StockSwing");
            }
            set
            {
                SetValByKey("StockSwing", value);
            }
        }

        public decimal StockSafeTop
        {
            get
            {
                return GetValDecimalByKey("StockSafeTop");
            }
            set
            {
                SetValByKey("StockSafeTop", value);
            }
        }
        public decimal StockSafeDown
        {
            get
            {
                return GetValDecimalByKey("StockSafeDown");
            }
            set
            {
                SetValByKey("StockSafeDown", value);
            }
        }
        public string StockBy
        {
            get
            {
                return GetValStringByKey("StockBy");
            }
            set
            {
                SetValByKey("StockBy", value);
            }
        }
        public bool IsTop
        {
            get
            {
                return GetValBooleanByKey("IsTop");
            }
            set
            {
                SetValByKey("IsTop", value);
            }
        }
        public bool IsDown
        {
            get
            {
                return GetValBooleanByKey("IsDown");
            }
            set
            {
                SetValByKey("IsDown", value);
            }
        }
        public decimal StockCenter
        {
            get
            {
                return GetValDecimalByKey("StockCenter");
            }
            set
            {
                SetValByKey("StockCenter", value);
            }
        }
        public decimal ResultMax
        {
            get
            {
                return GetValDecimalByKey("ResultMax");
            }
            set
            {
                SetValByKey("ResultMax", value);
            }
        }
        public decimal ResultMin
        {
            get
            {
                return GetValDecimalByKey("ResultMin");
            }
            set
            {
                SetValByKey("ResultMin", value);
            }
        }
        public decimal ResultWin
        {
            get
            {
                return GetValDecimalByKey("ResultWin");
            }
            set
            {
                SetValByKey("ResultWin", value);
            }
        }
        public decimal ResultCloseNum
        {
            get
            {
                return GetValDecimalByKey("ResultCloseNum");
            }
            set
            {
                SetValByKey("ResultCloseNum", value);
            }
        }
        #endregion

    }
    /// <summary>
    /// 推断记录 s
    /// </summary>
    public class RptDtls : EntitiesMyPK
    {

        #region 构造函数.
        /// <summary>
        /// 推断记录
        /// </summary>
        public RptDtls() { }
        /// <summary>
        /// 得到它的 Entity 
        /// </summary>
        public override Entity GetNewEntity
        {
            get
            {
                return new RptDtl();
            }
        }
        #endregion 构造函数.


        #region 为了适应自动翻译成java的需要,把实体转换成List.
        /// <summary>
        /// 转化成 java list,C#不能调用.
        /// </summary>
        /// <returns>List</returns>
        public System.Collections.Generic.IList<RptDtl> ToJavaList()
        {
            return (System.Collections.Generic.IList<RptDtl>)this;
        }
        /// <summary>
        /// 转化成list
        /// </summary>
        /// <returns>List</returns>
        public System.Collections.Generic.List<RptDtl> Tolist()
        {
            System.Collections.Generic.List<RptDtl> list = new System.Collections.Generic.List<RptDtl>();
            for (int i = 0; i < Count; i++)
            {
                list.Add((RptDtl)this[i]);
            }
            return list;
        }
        #endregion 为了适应自动翻译成java的需要,把实体转换成List.
    }
}
